#include <iostream>
#include <future>
#include <thread>
#include <chrono>

int add(int num1, int num2)
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "加法" << std::endl;
    return num1 + num2;
}

int main()
{
    // packaged_task  将一个函数进行二次封装，可以当做一个可调用对象执行任务，但是又不能像真正的函数一样使用
    // std::packaged_task<int(int, int)> task(add);
    // std::future<int> ret = task.get_future();

    // 可以执行任务而且必须执行, 否则 get 获取 future 会一直阻塞
    // task(1, 2);
    // 但是又不能完全当做一个函数使用
    // std::async(std::launch::async, task, 11, 22);
    // std::thread th1(task, 11, 22);


    // 但是可以将指针传递给另一个线程，通过解引用指针执行任务
    // 如果单纯指向一个局部对象，存在生命周期问题，可能会有风险
    auto ptask = std::make_shared<std::packaged_task<int(int, int)>>(add);
    std::future<int> ret = ptask->get_future();
    
    // 通过另一线程执行任务
    std::thread th1([ptask](){
        (*ptask)(11, 22);
    });

    // 获取结果
    std::cout << "等待任务执行结果" << std::endl;
    std::cout << ret.get() << std::endl;
    th1.join();
    return 0;
}